﻿using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using ST.Buz.Base;
using ST.Buz.Base.Buz_ViewModel;
using ST.Buz.Base.Entity;
using ST.Buz.Base.Enums;
using ST.Buz.Base.ViewModel;
using ST.Common.Util;
using ST.Common.Util.Model;
using ST.Common.Util.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ST.Buz.Service
{
	public partial interface IServiceFinanceRecvDue
	{
		PageData GetPageList(VMS_IMS_FinanceRecvDue searchModel, UserSession sessionCurrent);

		PageData GetAllPageList(VMS_IMS_FinanceRecvDue searchModel, UserSession sessionCurrent);

		List<IMS_FinanceRecvDue> GetList(VMS_IMS_FinanceRecvDue searchModel, UserSession sessionCurrent);

		int GetCount(VMS_IMS_FinanceRecvDue searchModel, UserSession sessionCurrent);

		/// <summary>
		/// 累计欠款统计
		/// </summary>
		/// <param name="partnerId"></param>
		/// <returns></returns>
		VM_PartnerStatistics GetStatistics(int partnerId);

		/// <summary>
		/// 生成应收款
		/// </summary>
		IMS_FinanceRecvDue Gen(int buzType, int buzID, int parterID, decimal amount, UserSession sessionCurrent);

		/// <summary>
		/// 
		/// </summary>
		IMS_FinanceRecvDue Add(int buzType, int buzID, UserSession sessionCurrent);

		IMS_FinanceRecvDue GetViewDetail(int id, UserSession sessionCurrent);

		IMS_FinanceRecvDue GetEditDetail(int id, UserSession sessionCurrent);

		int AddOrUpdate(IMS_FinanceRecvDue model, UserSession sessionCurrent);

		bool BatchAdd(IMS_FinanceRecvDue[] list, UserSession sessionCurrent);

		void AddOrUpdateWithinTrans(IMS_FinanceRecvDue model, UserSession sessionCurrent);

		bool Delete(int id, UserSession sessionCurrent);

		bool BatchDelete(int[] ids, UserSession sessionCurrent);

		void DeleteWithinTrans(FinanceBuzType buzType, int buzID, string ip, DateTime dtNow, UserSession sessionCurrent);

		string NextSNo();

		List<IMS_FinanceRecvDue> Get(FinanceBuzType buzType, int buzID);

		List<IMS_FinanceRecvDue> Get(int partnerID, int[] recvState, int[] dueIDs);

		bool UpdateDue(int[] ids, UserSession sessionCurrent);

		decimal GetTotalRecvDue(FinanceBuzType buzType, int buzID);

		decimal GetTotalRecved(FinanceBuzType buzType, int buzID);
	}

	public partial class ServiceFinanceRecvDue
	{
		private readonly IServiceSysLog serviceSysLog;

		public ServiceFinanceRecvDue(BuzContext ctx,
			IServiceSysLog _serviceSysLog,
			ILogger<ServiceFinanceRecvDue> log)
		{
			serviceSysLog = _serviceSysLog;
			context = ctx;
			logger = log;
		}

		private IQueryable<IMS_FinanceRecvDue> GetQuery(VMS_IMS_FinanceRecvDue searchModel, UserSession sessionCurrent)
		{
			var query = from m in context.FinanceRecvDue
						join p in context.Partner on m.PartnerID equals p.ID into ptmp
						from pall in ptmp.DefaultIfEmpty()
						select new IMS_FinanceRecvDue
						{
							ID = m.ID,
							SNo = m.SNo,
							Stage = m.Stage,
							DueDate = m.DueDate,
							BuzType = m.BuzType,
							BuzID = m.BuzID,
							BuzSNo = m.BuzSNo,
							PartnerID = m.PartnerID,
							PartnerName = pall.Name ?? m.PartnerName,
							TotalRecvDue = m.TotalRecvDue,
							TotalRecved = m.TotalRecved,
							Invoice = m.Invoice,
							Comment = m.Comment,
							StateNow = m.StateNow,
							RecvState = m.RecvState,
							AddDate = m.AddDate,
							AddManID = m.AddManID,
							AddManName = m.AddManName,
							OrgID = m.OrgID,
						};
			if (searchModel.partnerid.HasValue && searchModel.partnerid.Value > 0)
			{
				query = query.Where(m => m.PartnerID == searchModel.partnerid.Value);
			}
			else if (!string.IsNullOrWhiteSpace(searchModel.partnername))
			{
				query = query.Where(m => EF.Functions.Like(m.PartnerName, "%" + searchModel.partnername + "%"));
			}
			if (!string.IsNullOrWhiteSpace(searchModel.sno))
			{
				query = query.Where(m => m.SNo == searchModel.sno);
			}
			if (searchModel.buztype.HasValue && searchModel.buzid.HasValue && searchModel.buztype.Value > 0 && searchModel.buzid.Value > 0)
			{
				query = query.Where(m => m.BuzType == searchModel.buztype.Value && m.BuzID == searchModel.buzid.Value);
			}
			if (searchModel.date_s != DateTime.MinValue)
			{
				query = query.Where(m => m.DueDate >= searchModel.date_s);
			}
			if (searchModel.date_e != DateTime.MinValue)
			{
				query = query.Where(m => m.DueDate <= searchModel.date_e);
			}
			if (searchModel.duedate_s != DateTime.MinValue)
			{
				query = query.Where(m => m.DueDate >= searchModel.duedate_s);
			}
			if (searchModel.duedate_e != DateTime.MinValue)
			{
				query = query.Where(m => m.DueDate <= searchModel.duedate_e);
			}
			if (searchModel.state != null && searchModel.state.Length > 0)
			{
				query = searchModel.state.Length == 1 ? query.Where(m => m.RecvState == searchModel.state[0]) : query.Where(m => searchModel.state.Contains(m.RecvState));
			}
			if (searchModel.orgids != null && searchModel.orgids.Length > 0)
			{
				query = searchModel.orgids.Length == 1 ? query.Where(m => m.OrgID == searchModel.orgids[0]) : query.Where(m => searchModel.orgids.Contains(m.OrgID));
			}
			return query;
		}

		/// <summary>
		/// 分页列表
		/// </summary>
		public PageData GetPageList(VMS_IMS_FinanceRecvDue searchModel, UserSession sessionCurrent)
		{
			PageData result = null;
			try
			{
				searchModel.Validate();

				result = new PageData(searchModel.pnum.Value, searchModel.psize.Value);
				var query = GetQuery(searchModel, sessionCurrent);
				var sumCol = new string[] { "TotalRecvDue", "TotalRecved", "TotalRecvLeft" };
				object[] sumTotal = null;
				var sumResult = (from q in query
								 select new
								 {
									 TotalRecvDue = query.Sum(m => m.TotalRecvDue),
									 TotalRecved = query.Sum(m => m.TotalRecved),
									 Count = query.Count()
								 }).FirstOrDefault();
				if (sumResult == null)
				{
					sumTotal = new object[] { 0M, 0M, 0M };
				}
				else
				{
					sumTotal = new object[] {
						sumResult.TotalRecvDue,
						sumResult.TotalRecved,
						sumResult.TotalRecvDue-sumResult.TotalRecved,
					};
					result.total = sumResult.Count;
				}
				switch (searchModel.sortby)
				{
					default:
						query = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? query.OrderBy(e => e.ID) : query.OrderByDescending(e => e.ID);
						break;
				}
				result.LoadList(query);
				result.sumtotal = sumTotal;
				result.sumcol = sumCol;

			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.Message, ex);
			}
			return result;
		}


		public PageData GetAllPageList(VMS_IMS_FinanceRecvDue searchModel, UserSession sessionCurrent)
		{
			PageData result = null;
			try
			{
				searchModel.Validate();

				result = new PageData(searchModel.pnum.Value, searchModel.psize.Value);
				var query = GetQuery(searchModel, sessionCurrent);
				var queryGroup = from x in query
								 group x by new { x.PartnerID, x.PartnerName } into total
								 select new VM_IMS_FinanceRecvDue_All
								 {
									 PartnerID = total.Key.PartnerID,
									 PartnerName = total.Key.PartnerName,
									 TotalRecvDue = total.Sum(x => x.TotalRecvDue),
									 TotalRecved = total.Sum(x => x.TotalRecved),
									 TotalRecvLeft = total.Sum(x => x.TotalRecvDue - x.TotalRecved)
								 };
				var sumCol = new string[] { "TotalRecvDue", "TotalRecved", "TotalRecvLeft" };
				object[] sumTotal = null;
				var sumResult =
								(from q in queryGroup
								 select new
								 {
									 TotalRecvDue = queryGroup.Sum(m => m.TotalRecvDue),
									 TotalRecved = queryGroup.Sum(m => m.TotalRecved),
									 Count = queryGroup.Count()
								 }).FirstOrDefault();
				if (sumResult == null)
				{
					sumTotal = new object[] { 0M, 0M, 0M };
				}
				else
				{
					sumTotal = new object[] {
						sumResult.TotalRecvDue,
						sumResult.TotalRecved,
						sumResult.TotalRecvDue-sumResult.TotalRecved,
					};
					result.total = sumResult.Count;
				}
				switch (searchModel.sortby)
				{
					default:
						queryGroup = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? queryGroup.OrderBy(e => e.PartnerName) : queryGroup.OrderByDescending(e => e.PartnerName);
						break;
				}
				result.LoadList(queryGroup);
				result.sumtotal = sumTotal;
				result.sumcol = sumCol;

			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.Message, ex);
			}
			return result;
		}

		public List<IMS_FinanceRecvDue> GetList(VMS_IMS_FinanceRecvDue searchModel, UserSession sessionCurrent)
		{
			try
			{
				searchModel.Validate();

				var query = GetQuery(searchModel, sessionCurrent);
				return query.ToList();

			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.Message, ex);
			}
		}

		/// <summary>
		/// 获取总数
		/// </summary>
		public int GetCount(VMS_IMS_FinanceRecvDue searchModel, UserSession sessionCurrent)
		{
			try
			{
				var query = GetQuery(searchModel, sessionCurrent);

				return query.Count();
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.Message, ex);
			}
		}
		public VM_PartnerStatistics GetStatistics(int partnerId)
		{
			try
			{
				var query = from m in context.FinanceRecvDue
							where m.PartnerID == partnerId
							group m by m.PartnerID into total
							select new VM_PartnerStatistics
							{
								TotalRecvDue = total.Sum(x => x.TotalRecvDue),
								TotalRecved = total.Sum(x => x.TotalRecved),
								TotalRecvLeft = total.Sum(x => x.TotalRecvDue - x.TotalRecved)
							};

				return query.FirstOrDefault();
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.Message, ex);
			}
		}

		public IMS_FinanceRecvDue Gen(int buzType, int buzID, int parterID, decimal amount, UserSession sessionCurrent)
		{
			var model = new IMS_FinanceRecvDue();
			if (buzID > 0)
			{
				switch (buzType)
				{
					case (int)FinanceBuzType.加工订单:
						{
							var outOrder = (from m in context.Machining
											where m.ID == buzID
											select new { m.ID, m.SNo, m.PartnerID, m.PartnerName, m.Total }).SingleOrDefault();
							if (outOrder != null)
							{
								model.BuzID = outOrder.ID;
								model.BuzSNo = outOrder.SNo;
								model.PartnerID = outOrder.PartnerID;
								model.PartnerName = outOrder.PartnerName;
								model.BuzType = (int)FinanceBuzType.加工订单;
								model.TotalRecvDue = amount < outOrder.Total ? amount : outOrder.Total;
							}
						}
						break;
				}
			}
			else if (parterID > 0)
			{
				var partner = (from m in context.Partner
							   where m.ID == parterID
							   select new
							   {
								   m.ID,
								   m.Name
							   }).SingleOrDefault();
				if (partner != null)
				{
					model.PartnerID = partner.ID;
					model.PartnerName = partner.Name;
					model.TotalRecvDue = amount > 0 ? amount : 0;
				}
			}

			return model;
		}

		/// <summary>
		/// 
		/// </summary>
		public IMS_FinanceRecvDue Add(int buzType, int buzID, UserSession sessionCurrent)
		{
			try
			{
				if (buzType <= 0 || buzID <= 0)
				{
					throw new ArgumentException("业务类型、订单ID不能为空");
				}
				if (sessionCurrent == null)
				{
					throw new AuthException("用户未登录或登录已过期");
				}
				switch (buzType)
				{
					case (int)FinanceBuzType.加工订单:
						{
							var orderInfo = (from m in context.Machining where m.ID == buzID select new { m.Total, m.SNo, m.PartnerID, m.PartnerName }).SingleOrDefault();
							if (orderInfo == null)
							{
								throw new BuzException("未找到相关订单");
							}
							var dueTotal = (from m in context.FinanceRecvDue where m.BuzType == buzType && m.BuzID == buzID select m.TotalRecvDue).Sum();
							if (dueTotal == orderInfo.Total)
							{
								throw new BuzException("已创建应付款");
							}
							else if (dueTotal < orderInfo.Total)
							{
								var dueRecv = new IMS_FinanceRecvDue()
								{
									BuzID = buzID,
									BuzType = buzType,
									BuzSNo = orderInfo.SNo,
									TotalRecvDue = orderInfo.Total - dueTotal,
									TotalRecved = 0,
									PartnerID = orderInfo.PartnerID,
									PartnerName = orderInfo.PartnerName,
									OrgID = sessionCurrent.OrgID,
								};
								return dueRecv;
							}
							else
							{
								throw new BuzException("订单金额与应收款金额不一致，请确认后修改相应的应收款信息");
							}
						}
					default:
						throw new BuzException("业务类型有误");
				}
			}
			catch (BuzException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (AuthException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (ArgumentException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.InnerException != null ? ex.InnerException.Message : ex.Message, ex);
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public bool BatchAdd(IMS_FinanceRecvDue[] list, UserSession sessionCurrent)
		{
			try
			{
				if (list == null || list.Length == 0)
				{
					throw new ArgumentNullException("model");
				}

				if (sessionCurrent == null)
				{
					throw new ArgumentNullException("sessionCurrent");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						foreach (var model in list)
						{
							model.AddDate = dtNow;
							model.AddManID = sessionCurrent.UserID;
							model.AddManName = sessionCurrent.UserName;
							model.SNo = NextSNo();
							model.RecvState = (int)FinancePayRecvState.未收;
							//model.StateNow = (int)StockOutOrderState.待审核;
							Add(model);
						}
						#endregion
						trans.Commit();

						return true;
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.InnerException != null ? ex.InnerException.Message : ex.Message, ex);
			}
		}

		/// <summary>
		/// 获取详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public IMS_FinanceRecvDue GetViewDetail(int id, UserSession sessionCurrent)
		{
			IMS_FinanceRecvDue model = null;
			try
			{
				model = Get(id);
				if (model == null)
				{
					throw new EntityNotFoundException("未找到id为" + id + "的记录");
				}
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (EntityNotFoundException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.Message, ex);
			}
			return model;
		}

		/// <summary>
		/// 获取详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public IMS_FinanceRecvDue GetEditDetail(int id, UserSession sessionCurrent)
		{
			return GetViewDetail(id, sessionCurrent);
		}

		/// <summary>
		/// 新增或修改保存
		/// </summary>
		public int AddOrUpdate(IMS_FinanceRecvDue model, UserSession sessionCurrent)
		{
			try
			{
				if (model == null)
				{
					throw new ArgumentNullException("model");
				}

				if (sessionCurrent == null)
				{
					throw new ArgumentNullException("sessionCurrent");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						AddOrUpdateWithinTrans(model, sessionCurrent);
						#endregion
						trans.Commit();

						return model.ID;
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.InnerException != null ? ex.InnerException.Message : ex.Message, ex);
			}
		}

		public void AddOrUpdateWithinTrans(IMS_FinanceRecvDue model, UserSession sessionCurrent)
		{
			DateTime dtNow = DateTime.Now;
			//string ip = GetRequestIP();

			if (model.ID > 0)
			{
				Update(model);

				UpdateDue(new int[] { model.ID }, sessionCurrent);
			}
			else
			{
				model.AddDate = dtNow;
				model.AddManID = sessionCurrent.UserID;
				model.AddManName = sessionCurrent.UserName;
				model.SNo = NextSNo();
				model.RecvState = (int)FinancePayRecvState.未收;
				//model.StateNow = (int)StockOutOrderState.待审核;
				model.OrgID = sessionCurrent.OrgID;
				Add(model);
			}
		}

		/// <summary>
		/// 删除具体操作
		/// </summary>
		/// <param name="id"></param>
		/// <param name="ip"></param>
		/// <param name="dtNow"></param>
		/// <param name="sessionCurrent"></param>
		protected void DeleteWithinTrans(int id, string ip, DateTime dtNow, UserSession sessionCurrent)
		{
			IMS_FinanceRecvDue modelOld = Get(id, true);
			if (context.FinanceRecvDetail.Any(m => m.DueID == modelOld.ID))
			{
				throw new BuzException($"编号为[{modelOld.SNo}]的应收款已有关联的收款单信息，不能删除");
			}
			Delete(modelOld);

			serviceSysLog.Add(sessionCurrent, ip, $"删除编号为[{modelOld.SNo}]的应收款信息，原信息：", modelOld, dtNow);
		}

		/// <summary>
		/// 删除用户
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public bool Delete(int id, UserSession sessionCurrent)
		{
			bool success = false;
			try
			{
				if (id <= 0)
				{
					throw new ArgumentNullException("id");
				}
				if (sessionCurrent == null)
				{
					throw new ArgumentNullException("sessionCurrent");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();

						DeleteWithinTrans(id, ip, dtNow, sessionCurrent);
						#endregion

						trans.Commit();
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}

				success = true;
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.InnerException != null ? ex.InnerException.Message : ex.Message, ex);
			}
			return success;
		}

		/// <summary>
		/// 批量删除用户
		/// </summary>
		/// <returns></returns>
		public bool BatchDelete(int[] ids, UserSession sessionCurrent)
		{
			bool success = false;
			try
			{
				if (ids == null || ids.Length == 0)
				{
					throw new ArgumentNullException("ids");
				}
				if (sessionCurrent == null)
				{
					throw new ArgumentNullException("sessionCurrent");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();

						foreach (int id in ids)
						{
							DeleteWithinTrans(id, ip, dtNow, sessionCurrent);
						}
						#endregion

						trans.Commit();
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}

				success = true;
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.InnerException != null ? ex.InnerException.Message : ex.Message, ex);
			}
			return success;
		}

		/// <summary>
		/// 删除订单相关的应收款
		/// </summary>
		/// <param name="type"></param>
		/// <param name="buzID"></param>
		/// <returns></returns>
		public void DeleteWithinTrans(FinanceBuzType buzType, int buzID, string ip, DateTime dtNow, UserSession sessionCurrent)
		{
			var listOld = (from m in context.FinanceRecvDue
						   where m.BuzType == (int)buzType && m.BuzID == buzID
						   select m).AsNoTracking().ToList();
			var ids = listOld.Select(x => x.ID);
			if (context.FinanceRecvDetail.Any(m => ids.Contains(m.DueID)))
			{
				throw new BuzException($"应收款已有关联的收款单信息，不能删除");
			}
			foreach (var modelOld in listOld)
			{
				Delete(modelOld);
				serviceSysLog.Add(sessionCurrent, ip, $"删除编号为[{modelOld.SNo}]的应收款信息，原信息：", modelOld, dtNow);
			}
		}

		/// <summary>
		/// 获取下一个流水号
		/// </summary>
		/// <returns></returns>
		public string NextSNo()
		{
			try
			{
				DateTime dtNow = DateTime.Now;
				string prefix = "YS-" + DateTime.Now.ToString("yyyyMMdd-");
				string maxSNo = context.FinanceRecvDue.Where(m => EF.Functions.Like(m.SNo, prefix + "%")).Max(m => m.SNo);
				int maxNo = 0;
				if (!string.IsNullOrEmpty(maxSNo))
				{
					int.TryParse(maxSNo.Substring(prefix.Length), out maxNo);
				}

				return prefix + (maxNo + 1).ToString().PadLeft(4, '0');
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.Message, ex);
			}
		}

		/// <summary>
		/// 获取相关联的所有类型应收款
		/// </summary>
		/// <param name="type"></param>
		/// <param name="buzID"></param>
		/// <returns></returns>
		public List<IMS_FinanceRecvDue> Get(FinanceBuzType buzType, int buzID)
		{
			var query = from m in context.FinanceRecvDue
						where m.BuzType == (int)buzType && m.BuzID == buzID
						select m;
			return query.AsNoTracking().ToList();
		}

		/// <summary>
		/// 获取客户或供应商的所有应收款
		/// </summary>
		/// <param name="type"></param>
		/// <param name="buzID"></param>
		/// <returns></returns>
		public List<IMS_FinanceRecvDue> Get(int partnerID, int[] recvState, int[] dueIDs)
		{
			try
			{
				var query = from m in context.FinanceRecvDue
							where m.PartnerID == partnerID
							select m;
				if (recvState != null && recvState.Length > 0)
				{
					query = query.Where(m => recvState.Contains(m.RecvState));
				}
				if (dueIDs != null && dueIDs.Length > 0)
				{
					query = query.Where(m => dueIDs.Contains(m.ID));
					//query = query.Union(from m in context.FinanceRecvDue
					//					where dueIDs.Contains(m.ID)
					//					select m);
				}
				return query.AsNoTracking().ToList();
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (BuzException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.InnerException != null ? ex.InnerException.Message : ex.Message, ex);
			}
		}

		public bool UpdateDue(int[] ids, UserSession sessionCurrent)
		{
			try
			{
				if (ids == null || ids.Length == 0)
				{
					throw new ArgumentNullException("应收款");
				}
				string sqlSum = "UPDATE IMS_FinanceRecvDue SET TotalRecved = ISNULL(total.Recved, 0) FROM(SELECT SUM(Recved) AS Recved FROM IMS_FinanceRecvDetail WHERE DueID = @DueID) total WHERE ID = @DueID";
				string sqlState = "UPDATE IMS_FinanceRecvDue SET RecvState = (CASE WHEN TotalRecved=0 THEN " + (int)FinancePayRecvState.未收 + " WHEN TotalRecved >= TotalRecvDue THEN " + (int)FinancePayRecvState.已收清 + " ELSE " + (int)FinancePayRecvState.部分已收 + " END) WHERE ID = @DueID";
				foreach (int id in ids)
				{
					var paras = new SqlParameter[]{
						new SqlParameter("@DueID",id),
					};
					context.Database.ExecuteSqlRaw(sqlSum, paras);
					context.Database.ExecuteSqlRaw(sqlState, paras);
				}
				return true;
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (BuzException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.InnerException != null ? ex.InnerException.Message : ex.Message, ex);
			}
		}

		/// <summary>
		/// 获取应收款应收总额
		/// </summary>
		public decimal GetTotalRecvDue(FinanceBuzType buzType, int buzID)
		{
			decimal total = 0M;
			try
			{
				if (buzID <= 0)
				{
					throw new ArgumentNullException("相关单据");
				}
				total = context.FinanceRecvDue
					.Where(m => m.BuzType == (int)buzType && m.BuzID == buzID)
					.Sum(m => m.TotalRecvDue);
				return total;
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (BuzException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.InnerException != null ? ex.InnerException.Message : ex.Message, ex);
			}
		}

		/// <summary>
		/// 获取应收款已收总额
		/// </summary>
		public decimal GetTotalRecved(FinanceBuzType buzType, int buzID)
		{
			decimal total = 0M;
			try
			{
				if (buzID <= 0)
				{
					throw new ArgumentNullException("相关单据");
				}
				total = context.FinanceRecvDue
					.Where(m => m.BuzType == (int)buzType && m.BuzID == buzID)
					.Sum(m => m.TotalRecved);
				return total;
			}
			catch (ArgumentNullException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (BuzException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.InnerException != null ? ex.InnerException.Message : ex.Message, ex);
			}
		}
	}
}